using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;

namespace PowerBot
{
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    public class DebugWriter
    {
        public DebugWriter(string filename, TextBox logTB)
        {
            Encoding enc = System.Text.Encoding.GetEncoding(1251);
            FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
            Debug.Listeners.Add(new TextWriterTraceListener(new StreamWriter(fs, enc)));
            if(logTB!=null)
                Debug.Listeners.Add(new TextWriterTraceListener(new TextBoxWriter(logTB)));
            Debug.AutoFlush = true;
        }

        public DebugWriter(string filename)
            :this(filename, null)
        {
        }
    }

    [System.Diagnostics.DebuggerStepThroughAttribute()]
    public class DebugWriterTextBox: TextBox
    {
        private string _logFileName;
        [Category("Debug"),
        Description("Output file name")]
        public string LogFileName 
        {
            get{ return _logFileName;}
            set
            {
                if (_fileWriter != null)
                {
                    Debug.Listeners.Remove(_fileWriter);
                    _fileWriter.Dispose();
                    _fileWriter = null;
                }

                _logFileName = value;

                if(_logFileName==null)
                    return;

                FileStream fs = new FileStream(_logFileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
                _fileWriter = new TextWriterTraceListener(new StreamWriter(fs, _logFileEncoding));
                Debug.Listeners.Add(_fileWriter);
            }
        }

        private FileMode _logWriteMode = FileMode.Create;
        [Category("Debug"),
        Description("Output file creation/writing mode")]
        public FileMode LogWriteMode
        {
            get{ return _logWriteMode;}
            set{ _logWriteMode = value;}
        }

        private Encoding _logFileEncoding = System.Text.Encoding.GetEncoding(1251);
        [Category("Debug"),
        Description("Output file encoding")]
        public Encoding LogFileEncoding
        {
            get { return _logFileEncoding;}
            set{ _logFileEncoding = value;}
        }

        private TextWriterTraceListener _fileWriter;

        public DebugWriterTextBox()
        {
            Debug.Listeners.Add(new TextWriterTraceListener(new TextBoxWriter(this)));
            Debug.AutoFlush = true;

            this.Multiline = true;
            this.WordWrap = true;
        }
    }

    [System.Diagnostics.DebuggerStepThroughAttribute()]
    public class TextBoxWriter : System.IO.TextWriter
    {
        public delegate void UpdateTextDelegate(string pString);

        TextBox _textBox;

        public TextBoxWriter(System.Windows.Forms.TextBox pTextBox)
        {
            _textBox = pTextBox;
        }


        public override void WriteLine(string value)
        {
            object[] x = { value };
            if (_textBox.InvokeRequired)
            {
                _textBox.Invoke(new UpdateTextDelegate(UpdateText), new object[] { value });
            }
            else
            {
                if (value == null) return;
                if(_textBox.Text.Length+value.Length>32700)
                    _textBox.Text=_textBox.Text.Substring(_textBox.Text.Length/2) + value +"\r\n";
                else
                    _textBox.Text += value + "\r\n";

                _textBox.SelectionStart = _textBox.Text.Length;
                _textBox.SelectionLength = 0;
                _textBox.ScrollToCaret();
            }

        }

        public override System.Text.Encoding Encoding
        {
            get
            {
                // TODO: Add TextBoxWriter.Encoding getter implementation
                return null;
            }
        }
        private void UpdateText(string pString)
        {
            if (pString == null) return;
            if (_textBox.Text.Length + pString.Length > 32700)
                _textBox.Text = _textBox.Text.Substring(_textBox.Text.Length / 2) + pString + "\r\n";
            else
                _textBox.Text += pString + "\r\n";
            _textBox.SelectionStart = _textBox.Text.Length;
            _textBox.SelectionLength = 0;
            _textBox.ScrollToCaret();

        }
    }
}

